import { Injectable, Injector } from '@angular/core';
import { Router,ActivatedRoute } from '@angular/router';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpErrorResponse,
  HttpEvent,
  HttpResponseBase,
} from '@angular/common/http';
import { Observable, of, throwError, observable } from 'rxjs';
import { mergeMap, catchError, retry } from 'rxjs/operators';

import { OAuth2Service } from '../../@core/service/login-service/api/oAuth2.service';
import { LoadingService } from '../../@theme/common/loading.service';
import { MessageService } from '../service/subscribe/message.service';
import { MissionService } from '../service/subscribe/mission.service';

const CODEMESSAGE = {
  200: '服务器成功返回请求的数据。',
  400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
};

/**
 * 默认HTTP拦截器，在app.module.ts中注册`
 */
@Injectable()

export class DefaultInterceptor implements HttpInterceptor {
  private session = sessionStorage;
  private timer;                                                      // 倒计时定时器
  private queue : Object = {};
  constructor(
    private injector: Injector, 
    public authService: OAuth2Service,
    public load:LoadingService,
    public route:Router,
    private missionService: MissionService,
    private messageService: MessageService
  ) {}
  // 在底部显示错误信息

  private goTo(url: string) {
    setTimeout(() => this.injector.get(Router).navigateByUrl(url));
  }

  private checkStatus(ev: HttpResponseBase) {
    if ((ev.status >= 200 && ev.status < 300) || ev.status === 401) {
      return;
    }               
    const errortext = CODEMESSAGE[ev.status] || ev.statusText;
  }

  private handleData(ev: HttpResponseBase, url: string): Observable<any> {
    // 取消Loading
   let  {url:routeUrl}  =  this.route;
    
    if(routeUrl != '/login' && !url.includes("file/bizfile/approve/flow/")&& !url.includes('/taskApi/task')){
        delete this.queue[url];
        if(Object.keys(this.queue).length == 0){
          this.load.closeLoading();
        }
    }
    this.checkStatus(ev);
    // 业务处理：一些通用操作
    switch (ev.status) {
      case 200:
        let { url } =  ev;
        if(url.includes("/authApi")||url.includes("/loginApi")){
          if(ev['body']){
            if(!ev['body']['rel']){
              let msg = ev['body']['message'] || "服务器异常，请刷新重试";
              this.messageService.createMessage(false, msg);
              this.injector.get(Router).navigateByUrl("/login");
              throw ev['body']['message']
            }
          }
        }
        break;
      case 401: {
        alert(CODEMESSAGE[ev.status]);

      };break;
      case 403:
      case 404:
       console.log(CODEMESSAGE[ev.status]);
       break;
      case 500: {
        if(ev['body']) {
          this.messageService.createMessage(false, ev['message']);
        } else if(ev['error']){
          let msg = ev['error']['message'] || "服务器异常，请刷新重试";
          this.messageService.createMessage(false, msg);
        } else {
          this.messageService.createMessage(false, "服务器异常，请刷新重试");
        }
        this.missionService.confirmMission('login-interceotor', 'login', false);
        return throwError(ev);
      }; break;
      default:
        if (ev instanceof HttpErrorResponse) {
          console.warn('未可知错误，可能由于后端不支持CORS或无效配置引起', ev);
          return throwError(ev);
        }
        break;
    }
    return of(ev);
  }

  // 用户无操作
  private userHasNoOperation() {
    clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      alert("长时间未操作");
      this.injector.get(Router).navigateByUrl("/login");
      this.session.clear();
    },1 * 60 * 60 * 1000);
  }

  // 刷新token
  private refreshToken() {
    let arg = {
      grantType: "refresh_token",
      accessToken: this.session.getItem('accessToken'),
      refreshToken: this.session.getItem('refreshToken')
    }
    this.authService.authTokenRefreshPost(arg.grantType, arg.refreshToken).subscribe(res => {
      
    }, error => {
      
    })
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let url = req.url;
    let token = this.session.getItem("accessToken") || "";
    let refreshToken = this.session.getItem("refreshToken") || "";
    let { url:routeUrl } = this.route;
    if(routeUrl != '/login' && !url.includes("file/bizfile/approve/flow/")&& !url.includes('/taskApi/task')){
    // 判断队列中是否有正在请求的地址
      if(Object.keys(this.queue).length == 0){
        this.load.showLoading();
      }
      this.queue[url] = url;
    }


    if(token == "") {
      // 判断用户是否登录
      this.goTo('login');
    } else{
      // 判断用户无操作
      this.userHasNoOperation();
    }
    // 统一加上token
    var headers = req.headers;
    headers = headers.set("accessToken", token);
    headers = headers.set("refreshToken", refreshToken);

    const newReq = req.clone({headers});
    
    return next.handle(newReq).pipe(
      mergeMap((event: any) => {
        // 允许统一对请求错误处理
        if (event instanceof HttpResponseBase) return this.handleData(event, url);
        // 若一切都正常，则后续操作
        return of(event);
      }),
      catchError((err: HttpErrorResponse) => this.handleData(err, url)),
    );
  }
}
